package com.od.message.processor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.od.message.protocol.IMDecoder;
import com.od.message.protocol.IMEncoder;
import com.od.message.protocol.IMMessage;
import com.od.message.protocol.IMP;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * MsgProcessor: 服务端用户中心，主要处理用户登录、退出、上线、下线、发送消息等行为动作的逻辑。
 */
public class MsgProcessor {
    //记录在线用户
    private static ChannelGroup onlineUsers = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    //拓展属性
    private static final AttributeKey<String> NICK_NAME = AttributeKey.valueOf("nickName");
    private static final AttributeKey<String> IP_ADDR = AttributeKey.valueOf("ipAddr");
    private static final AttributeKey<JSONObject> ATTRS = AttributeKey.valueOf("attrs");
    private static final AttributeKey<String> FROM = AttributeKey.valueOf("from");

    //自定义编解码器
    private IMDecoder decoder = new IMDecoder();
    private IMEncoder encoder = new IMEncoder();

    /**
     * 获取用户昵称
     * @param client
     * @return
     */
    public String getNickName(Channel client) {
        return client.attr(NICK_NAME).get();
    }

    /**
     * 获取用户ip
     * @param client
     * @return
     */
    public String getAddress(Channel client) {
        return client.remoteAddress().toString().replaceFirst("/", "");
    }

    /**
     * 获取用户ip
     * @param client
     * @return
     */
    public JSONObject getAttrs(Channel client) {
        try {
            return client.attr(ATTRS).get();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取用户ip
     * @param client
     * @return
     */
    public void setAttrs(Channel client, String key, Object value) {
        try {
            JSONObject json = client.attr(ATTRS).get();
            json.put(key, value);
            client.attr(ATTRS).set(json);
        } catch (Exception e) {
            JSONObject json = new JSONObject();
            json.put(key, value);
            client.attr(ATTRS).set(json);
        }
    }

    /**
     * 退出通知
     * @param client
     */
    public void logout(Channel client) {
        //若nickname为空，即不遵守协议的连接，无法登陆
        if (getNickName(client) == null) {
            return;
        }
        for (Channel channel : onlineUsers) {
            IMMessage request = new IMMessage(IMP.SYSTEM.getName(), System.currentTimeMillis(), onlineUsers.size(), getNickName(client) + "离开");
            String content = encoder.encode(request);
            channel.writeAndFlush(new TextWebSocketFrame(content));
        }
        onlineUsers.remove(client);
    }

    /**
     * 发送消息
     * @param client
     * @param msg
     */
    public void sendMsg(Channel client, IMMessage msg) {
        encoder.encode(msg);
    }

    public void sendMsg(Channel client, String msg) {
        IMMessage request = decoder.decode(msg);
        if (request == null) {
            return;
        }
        String addr = getAddress(client);
        if (request.getCmd().equals(IMP.LOGIN.getName())) {
            client.attr(NICK_NAME).getAndSet(request.getSender());
            client.attr(IP_ADDR).getAndSet(addr);
            client.attr(FROM).getAndSet(request.getTerminal());
            onlineUsers.add(client);

            for (Channel channel : onlineUsers) {
                if (channel != client) {
                    request = new IMMessage(IMP.SYSTEM.getName(), System.currentTimeMillis(), onlineUsers.size(), getNickName(client) + "加入");
                } else {
                    request = new IMMessage(IMP.SYSTEM.getName(), System.currentTimeMillis(), onlineUsers.size(), "已与服务器建立连接！");
                }

                if ("Console".equals(channel.attr(FROM).get())) {
                    channel.writeAndFlush(request);
                    continue;
                }

                String content  = encoder.encode(request);
                channel.writeAndFlush(new TextWebSocketFrame(content));
            }
        } else if (request.getCmd().equals(IMP.CHAT.getName())) {
            for (Channel channel : onlineUsers) {
                if (channel == client) {
                    request.setSender("you");
                } else {
                    request.setSender(getNickName(client));
                }
                request.setTime(System.currentTimeMillis());

                if ("Console".equals(channel.attr(FROM).get()) && channel != client) {
                    channel.writeAndFlush(request);
                    continue;
                }

                String content  = encoder.encode(request);
                channel.writeAndFlush(new TextWebSocketFrame(content));
            }
        } else if (request.getCmd().equals(IMP.FLOWER.getName())) {
            JSONObject attrs = getAttrs(client);
            long currentTime = System.currentTimeMillis();
            if (attrs == null) {
                long lastTime = attrs.getLongValue("lastFlowerTime");
                //cd:60s
                int seconds = 60;
                long sub = currentTime - lastTime;
                if (sub < 1000 * seconds) {
                    request.setSender("you");
                    request.setSender(IMP.SYSTEM.getName());
                    request.setContent("送花太过频繁，" + (seconds - Math.round(sub/1000)) + "秒后再试" );
                    String content = encoder.encode(request);
                    client.writeAndFlush(new TextWebSocketFrame(content));
                    return;
                }
            }
            for (Channel channel : onlineUsers) {
                if (channel == client) {
                    request.setSender("you");
                    request.setContent("你送了大家一波鲜花");
                    setAttrs(client, "lastFlowerTime", currentTime);
                } else {
                    request.setSender(getNickName(client));
                    request.setContent(getNickName(client) + "送来一波鲜花");
                }
                request.setTime(System.currentTimeMillis());

                String content  = encoder.encode(request);
                channel.writeAndFlush(new TextWebSocketFrame(content));
            }
        }
    }
}
